package com.viking.car;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PushbackInputStream;
import java.net.Socket;
import java.util.Map;

/**
 * 处理客户端请求的线程
 */
public class SocketHandler extends Thread{
    private Socket socket;
    public SocketHandler(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        responseCommand(socket);
    }
    //响应客户端请求
    public void responseCommand(Socket socket){
        OutputStream ops = null;
        InputStream ins = null;
        PushbackInputStream pis = null;
        int commandId = 0;
        int sequenceId = 0;
        try {
            ins = socket.getInputStream();
            ops = socket.getOutputStream();
            byte[] bytes = MessageUtils.readMessageBytes(ins);
            if(bytes == null){
                return;
            }
            Message req = MessageUtils.bytesToMessage(bytes,false);
            System.out.println("请求消息是："+req);
            socket.shutdownInput();
            //验证客户端请求消息的合法性
            commandId = req.getMessageHeader().getCommand_id();
            sequenceId = req.getMessageHeader().getSequence_id();
            int respCommandId = Constants.COMMANDID_MAP.get(commandId);
            String code = checkMessage(req, respCommandId);
            //-----------------------------响应消息--------------------------------------------
            Message resp = MessageUtils.generateMessage(code, respCommandId,sequenceId,true);
            ops.write(MessageUtils.messageToBytes(resp));
            ops.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            MessageUtils.close(ins);
            MessageUtils.close(ops);
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println("服务端处理完毕!");
        }
    }

    /**
     * 根据请求消息进行具体的操作，并将处理结果响应码返回
     * @param req
     * @param respCommandId
     * @return
     */
    //todo 验证客户端请求消息的合法性
    private String checkMessage(Message req, int respCommandId) {
        try {
            //根据要响应的commandId得到响应码
            Map<Integer,String> map = Constants.RESP_CODE_MAP.get(respCommandId);
            if (req == null){ //解析失败,消息错误
                return map.get(Constants.MESSAGE_SRUCT_ERROR);
            }
            //todo 其他错误：token错误，重复动作错误
            Token token = Token.parseToken(req.getMessageBody().getBody());
            System.out.println("得到的客户端token="+token.toFormatString());
            token.printReserved();
            //todo 校验通过后具体操作：取车，开门，锁门，还车

        }catch (IllegalArgumentException e){
            e.printStackTrace();
            return "10101";
        }
        //操作成功，返回成功的响应码
        return "0";
    }

}
